package de.htwds.mada.todolistDB.db;

import de.htwds.mada.todolistDB.model.Priority;
import de.htwds.mada.todolistDB.model.Todo;
import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;
import android.provider.BaseColumns;
import android.util.Log;

public class TodoContentProvider extends ContentProvider {

	private DatabaseHelper mDatabaseHelper;

	private static final String LOG = "TodoContentProvider";
	private static final String TABLE_NAME_TODO = "todo";
	private static final String TABLE_NAME_PRIORITY = "priority";

	public static final String SCHEME = "content://";
	public static final String AUTHORITY = "de.htwds.mada.todo";

	private static final UriMatcher sUriMatcher = new UriMatcher(
			UriMatcher.NO_MATCH);

	public static class Todos implements BaseColumns {

		public static final String PATH = "todos";
		public static final Uri CONTENT_URI = Uri.parse(SCHEME + AUTHORITY
				+ "/" + PATH);

		public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.de.htwds.mada.todo";
		public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.de.htwds.mada.todo";

		public static final String ID = Todo.TODO_ID_FIELD;
		public static final String TITLE = Todo.TITLE_FIELD;
		public static final String DESCRIPTION = Todo.DESC_FIELD;
		public static final String DATETIME = Todo.DATE_FIELD;
		public static final String PRIORITY_ID = Todo.PRIO_FIELD;
	}

	public static class Priorities implements BaseColumns {

		public static final String PATH = "priorities";
		public static final Uri CONTENT_URI = Uri.parse(SCHEME + AUTHORITY
				+ "/" + PATH);

		public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.de.htwds.mada.todo";
		public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.de.htwds.mada.todo";

		public static final String ID = Priority.PRIO_ID_FIELD;
		public static final String NAME = Priority.NAME_FIELD;
	}

	private static final int TODOS = 100;
	private static final int TODOS_ID = 101;
	private static final int PRIORITIES = 200;
	private static final int PRIORITIES_ID = 201;

	static {
		sUriMatcher.addURI(AUTHORITY, Todos.PATH, TODOS);
		sUriMatcher.addURI(AUTHORITY, Todos.PATH + "/#", TODOS_ID);
		sUriMatcher.addURI(AUTHORITY, Priorities.PATH, PRIORITIES);
		sUriMatcher.addURI(AUTHORITY, Priorities.PATH + "/#", PRIORITIES_ID);
	}

	@Override
	public int delete(Uri uri, String selection, String[] selectionArgs) {
		int uriCode = sUriMatcher.match(uri);

		switch (uriCode) {
		case TODOS:
			int todoAffected = deleteTodo(selection, selectionArgs);
			return todoAffected;
		case PRIORITIES:
			int priorityAffected = deletePriority(selection, selectionArgs);
			return priorityAffected;
		default:
			return 0;
		}
	}

	@Override
	public String getType(Uri uri) {
		int uriCode = sUriMatcher.match(uri);
		switch (uriCode) {
		case TODOS:
			return Todos.CONTENT_TYPE;
		case TODOS_ID:
			return Todos.CONTENT_ITEM_TYPE;
		case PRIORITIES:
			return Priorities.CONTENT_TYPE;
		case PRIORITIES_ID:
			return Priorities.CONTENT_ITEM_TYPE;
		default:
			return null;
		}
	}

	@Override
	public Uri insert(Uri uri, ContentValues values) {
		int uriCode = sUriMatcher.match(uri);
		switch (uriCode) {
		case TODOS:
			long todoId = insertTodo(values);
			return ContentUris.appendId(uri.buildUpon(), todoId).build();
		case PRIORITIES:
			long priorityId = insertPriority(values);
			return ContentUris.appendId(uri.buildUpon(), priorityId).build();
		default:
			return null;
		}
	}

	@Override
	public boolean onCreate() {
		return false;
	}

	@Override
	public Cursor query(Uri uri, String[] projection, String selection,
			String[] selectionArgs, String sortOrder) {
		int uriCode = sUriMatcher.match(uri);

		switch (uriCode) {
		case TODOS:
			return queryForAllTodos(projection, selection, selectionArgs,
					sortOrder);
		case TODOS_ID:
			long todoId = ContentUris.parseId(uri);
			return queryTodo(todoId, projection, selection, selectionArgs,
					sortOrder);
		case PRIORITIES:
			return queryForAllPriorities(projection, selection, selectionArgs,
					sortOrder);
		case PRIORITIES_ID:
			long priorityId = ContentUris.parseId(uri);
			return queryPriority(priorityId, projection, selection,
					selectionArgs, sortOrder);
		default:
			return null;
		}
	}

	@Override
	public int update(Uri uri, ContentValues values, String selection,
			String[] selectionArgs) {
		int uriCode = sUriMatcher.match(uri);

		switch (uriCode) {
		case TODOS:
			int todoAffected = updateTodo(values, selection, selectionArgs);
			return todoAffected;
		case PRIORITIES:
			int priorityAffected = updatePriority(values, selection,
					selectionArgs);
			return priorityAffected;
		default:
			return 0;
		}
	}

	private Cursor queryForAllTodos(String[] projection, String selection,
			String[] selectionArgs, String sortOrder) {
		Cursor cursor = null;
		SQLiteDatabase db = mDatabaseHelper.getReadableDatabase();

		try {
			cursor = db.query(TABLE_NAME_TODO, projection, selection,
					selectionArgs, null, null, sortOrder);
		} catch (Exception e) {
			Log.e(LOG, "queryForAllTodos()", e);
		}
		return cursor;
	}

	private Cursor queryTodo(long id, String[] projection, String selection,
			String[] selectionArgs, String sortOrder) {
		Cursor cursor = null;
		SQLiteDatabase db = mDatabaseHelper.getReadableDatabase();

		try {
			String selString = Todo.TODO_ID_FIELD + "=" + id;
			if (!selection.isEmpty())
				selString += "AND" + selection;
			cursor = db.query(TABLE_NAME_TODO, projection, selString,
					selectionArgs, null, null, sortOrder);
		} catch (Exception e) {
			Log.e(LOG, "queryTodo()", e);
		}
		return cursor;
	}

	private Cursor queryForAllPriorities(String[] projection, String selection,
			String[] selectionArgs, String sortOrder) {
		Cursor cursor = null;
		SQLiteDatabase db = null;

		try {
			db = mDatabaseHelper.getReadableDatabase();
			cursor = db.query(TABLE_NAME_PRIORITY, projection, selection,
					selectionArgs, null, null, sortOrder);
		} catch (Exception e) {
			Log.e(LOG, "queryForAllPriorities()", e);
		}
		return cursor;
	}

	private Cursor queryPriority(long id, String[] projection,
			String selection, String[] selectionArgs, String sortOrder) {
		Cursor cursor = null;
		SQLiteDatabase db = mDatabaseHelper.getReadableDatabase();

		try {
			String selString = Priority.PRIO_ID_FIELD + "=" + id;
			if (!selection.isEmpty())
				selString += "AND" + selection;
			cursor = db.query(TABLE_NAME_PRIORITY, projection, selString,
					selectionArgs, null, null, sortOrder);
		} catch (Exception e) {
			Log.e(LOG, "queryPriority()", e);
		}
		return cursor;
	}

	private long insertTodo(ContentValues values) {
		long id = 0;
		SQLiteDatabase db = mDatabaseHelper.getReadableDatabase();

		try {
			id = db.insert(TABLE_NAME_TODO, null, values);
		} catch (Exception e) {
			Log.e(LOG, "insertTodo()", e);
		}
		return id;
	}

	private long insertPriority(ContentValues values) {
		long id = 0;
		SQLiteDatabase db = mDatabaseHelper.getReadableDatabase();

		try {
			id = db.insert(TABLE_NAME_PRIORITY, null, values);
		} catch (Exception e) {
			Log.e(LOG, "insertPriority()", e);
		}
		return id;
	}

	private int updateTodo(ContentValues values, String selection,
			String[] selectionArgs) {
		int affected = 0;
		SQLiteDatabase db = mDatabaseHelper.getReadableDatabase();

		try {
			affected = db.update(TABLE_NAME_TODO, values, selection,
					selectionArgs);
		} catch (Exception e) {
			Log.e(LOG, "updateTodo()", e);
		}
		return affected;
	}

	private int updatePriority(ContentValues values, String selection,
			String[] selectionArgs) {
		int affected = 0;
		SQLiteDatabase db = mDatabaseHelper.getReadableDatabase();

		try {
			affected = db.update(TABLE_NAME_PRIORITY, values, selection,
					selectionArgs);
		} catch (Exception e) {
			Log.e(LOG, "updatePriority()", e);
		}
		return affected;
	}

	private int deleteTodo(String selection, String[] selectionArgs) {
		int affected = 0;
		SQLiteDatabase db = mDatabaseHelper.getReadableDatabase();
		try {
			affected = db.delete(TABLE_NAME_TODO, selection, selectionArgs);
		} catch (Exception e) {
			Log.e(LOG, "deleteTodo()", e);
		}
		return affected;
	}

	private int deletePriority(String selection, String[] selectionArgs) {
		int affected = 0;
		SQLiteDatabase db = mDatabaseHelper.getReadableDatabase();
		try {
			affected = db.delete(TABLE_NAME_PRIORITY, selection, selectionArgs);
		} catch (Exception e) {
			Log.e(LOG, "deletePriority()", e);
		}
		return affected;
	}

}
